#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#include <config.h>
#include <systems.h>
#include <drivers/bluetooth/btcore.h>

pthread_t bt_read_thread_id;
sem_t bt_read_thread_sem;
extern struct bluetooth_operations *bluetooth_ops;

int (*bluetooth_packet_proc)(void *arg);

int bluetooth_init(int (*handler)(void *))
{
    int ret = 0;
    
    if(!bluetooth_ops)
        return -1;
        
    if(bluetooth_ops->init)
        ret = bluetooth_ops->init();

    if(ret >= 0) {
        sem_init(&bt_read_thread_sem, 0, 0);
        pthread_create(&bt_read_thread_id, NULL, (void *(*)(void*))bluetooth_read_daemon, NULL);
        bluetooth_packet_proc = handler;
    }
    
    return ret;
}

int bluetooth_write(BT_PACKET *arg)
{
    if(!bluetooth_ops)
        return -1;
        
    if(bluetooth_ops->write)
        return bluetooth_ops->write(arg);

    return 0;
}

BT_PACKET *bluetooth_read(void)
{
    if(!bluetooth_ops)
        return NULL;
        
    if(bluetooth_ops->read)
        return bluetooth_ops->read();

    return 0;
}

void bluetooth_start(void *arg)
{
    sem_post(&bt_read_thread_sem);
}

void bluetooth_stop(void *arg)
{
    printf("Stopping Bluetooth ... ");
    sem_wait(&bt_read_thread_sem);
    printf("OK\n");
}

void bluetooth_read_daemon(void *arg)
{
    BT_PACKET *packet;
    
    if(!bluetooth_ops)
        return;
        
    while(1) {
        sem_wait(&bt_read_thread_sem);
        
        packet = bluetooth_read();
        if(!packet) {
            sem_post(&bt_read_thread_sem);
            continue;
        }
        
        if(bluetooth_packet_proc) {
            DPRINTF("Packet process routine invoked\n");
            bluetooth_packet_proc((void *)packet);
        }
        
        sem_post(&bt_read_thread_sem);
    }
}

